﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Wechat.Util.Request;

namespace Wechat.Util.Auth
{
    public class UserAuth
    {
        /// <summary>
        /// 获取签名认证字符串
        /// </summary>
        public static string GetAuthString(OnAuthRequset requset)
        {
            string
                API_KEY = requset.name,
                API_SECRET = requset.pwd,
                timestamp = GetTimestamp(DateTime.Now).ToString(),
                nonce = GetNonce();

            string
                join_str = GenJoinStr(timestamp, nonce, API_KEY),
                signature = GenEncryptString(join_str, API_SECRET);

            return GenAuthorization(API_KEY, timestamp, nonce, signature);
        }

        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <param name="time">本地时间</param>
        /// <returns>时间戳</returns>
        public static long GetTimestamp(DateTime time)
        {
            return (time.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        /// <summary>
        /// 获取随机nonce
        /// </summary>
        /// <returns></returns>
        public static string GetNonce()
        {
            return Guid.NewGuid().ToString().Replace("-", string.Empty);
        }

        /// <summary>
        /// 将timestamp、nonce、API_KEY 这三个字符串进行升序排列（依据字符串首位字符的ASCII码)，并join成一个字符串
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="API_KEY"></param>
        /// <returns></returns>
        public static string GenJoinStr(string timestamp, string nonce, string API_KEY)
        {
            List<string> beforesort = new List<string>();
            beforesort.Add(API_KEY);
            beforesort.Add(timestamp);
            beforesort.Add(nonce);

            beforesort.Sort();

            StringBuilder aftersort = new StringBuilder();
            for (int i = 0; i < beforesort.Count; i++)
            {
                aftersort.Append(beforesort[i]);
            }

            string join_str = aftersort.ToString();
            return join_str;
        }

        /// <summary>
        /// 用API_SECRET对join_str做hamc-sha256签名，且以16进制编码
        /// </summary>
        /// <param name="join_str"></param>
        /// <param name="API_SECRET"></param>
        /// <returns></returns>
        public static string GenEncryptString(string join_str, string API_SECRET)
        {
            StringBuilder sb = new StringBuilder();

            var encoding = new ASCIIEncoding();
            byte[] keyByte = encoding.GetBytes(API_SECRET);
            byte[] messageBytes = encoding.GetBytes(join_str);
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);

                foreach (byte b in hashmessage)
                {
                    sb.Append(b.ToString("x2"));
                }

                return sb.ToString();
            }
        }

        /// <summary>
        /// 将上述的值按照 #{k}=#{v} 并以 ',' join在一起
        /// </summary>
        /// <param name="API_KEY"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="signature"></param>
        /// <returns></returns>
        public static string GenAuthorization(string API_KEY, string timestamp, string nonce, string signature)
        {
            string authorization =
                "key=" + API_KEY
                + ",timestamp=" + timestamp
                + ",nonce=" + nonce
                + ",signature=" + signature;
            return authorization;
        }
    }
}
